package com.funny.stock.trade.controller;

import com.funny.stock.base.util.PropertiesCopyUtil;
import com.funny.stock.base.util.ResultUtil;
import com.funny.stock.base.vo.Result;
import com.funny.stock.base.vo.TradeType;
import com.funny.stock.data.collect.impl.RealTimeStockServiceDelegate;
import com.funny.stock.data.vo.RealtimeStockData;
import com.funny.stock.data.vo.StockConstants;
import com.funny.stock.data.vo.StockType;
import com.funny.stock.trade.dao.pojo.ComposeStockItemDO;
import com.funny.stock.trade.dao.pojo.DayTradeProfitDO;
import com.funny.stock.trade.dao.pojo.DayTradeRecordDO;
import com.funny.stock.trade.service.ComposeStockItemService;
import com.funny.stock.trade.service.DayTradePlanService;
import com.funny.stock.trade.service.DayTradeProfitService;
import com.funny.stock.trade.service.DayTradeRecordService;
import com.funny.stock.trade.vo.ComposeTradeProfitVO;
import com.funny.stock.trade.vo.DayTradePlanVO;
import com.funny.stock.trade.vo.DayTradeProfitVO;
import com.funny.stock.trade.vo.DayTradeRecordVO;
import com.funny.stock.trade.vo.T0TradePlanDetailVO;
import com.funny.stock.trade.vo.T0TradePlanListVO;
import com.funny.stock.user.util.UserSecurityUtil;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author pengl
 * @date 2020/05/17
 **/
@RestController
@RequestMapping("/stock/tradePlan/t0")
public class T0TradePlanController {
    public static final Logger logger = LoggerFactory.getLogger(T0TradePlanController.class);

    @Autowired
    DayTradePlanService tradePlanService;

    @Autowired
    DayTradeRecordService dayTradeRecordService;

    @Autowired
    ComposeStockItemService stockItemService;

    @Autowired
    RealTimeStockServiceDelegate realTimeStockServiceDelegate;


    @Autowired
    DayTradeProfitService dayTradeProfitService;

    @GetMapping("/list")
    public Result list(@RequestParam Long composeId){
        Long userId = UserSecurityUtil.getUserId();
        List<DayTradePlanVO> gridTradePlanDOS = tradePlanService.queryTradePlanList(userId.intValue(),composeId);
        if(CollectionUtils.isEmpty(gridTradePlanDOS))
            return ResultUtil.success(null);

        Map<String,Object> dataMap = new HashMap<>();
        List<T0TradePlanListVO> vos = PropertiesCopyUtil.copyPropertiesByList(gridTradePlanDOS, T0TradePlanListVO.class);
        Map<Long, ComposeTradeProfitVO> profitVOMap = dayTradeRecordService.queryComposeTradeProfitMap(userId, composeId, StockConstants.STOCK_STRATEGY_T0);
        BigDecimal sumProfit = BigDecimal.ZERO;
        for (T0TradePlanListVO listVO : vos) {
            ComposeTradeProfitVO profitVO = profitVOMap.get(listVO.getId());
            if(profitVO == null) {
                listVO.setProfitMoney(BigDecimal.ZERO);
                listVO.setProfitNumber(0L);
                continue;
            }
            listVO.setProfitMoney(profitVO.getProfitMoney());
            listVO.setProfitNumber(profitVO.getProfitNumber());
            sumProfit = sumProfit.add(profitVO.getProfitMoney());
        }
        dataMap.put("content",vos);
        dataMap.put("summaryProfit",sumProfit.setScale(2, BigDecimal.ROUND_HALF_UP).toString());
        return ResultUtil.success(dataMap);
    }

    @GetMapping("/detail/{id}")
    public Result<T0TradePlanDetailVO> detail(@PathVariable Long id){
        Long userId = UserSecurityUtil.getUserId();
        DayTradePlanVO planDO = tradePlanService.findByIdAndCreateId(id, userId);
        if(planDO == null) return ResultUtil.error("不存在的计划");

        T0TradePlanDetailVO detailVO = new T0TradePlanDetailVO();
        DayTradePlanVO dayTradePlanVO = PropertiesCopyUtil.copyProperties(planDO, DayTradePlanVO.class);
        detailVO.setPlanData(dayTradePlanVO);
        detailVO.setStockName(dayTradePlanVO.getStockName());
        detailVO.setStockCode(dayTradePlanVO.getStockCode());


        ComposeStockItemDO stockItemDO = stockItemService.queryStockItem(userId, planDO.getComposeId(), planDO.getCode());
        if(stockItemDO != null){
            detailVO.setStockNumber(stockItemDO.getStockNumber());

            RealtimeStockData realtimeData = realTimeStockServiceDelegate.getRealtimeData(stockItemDO.getStockCode(),
                    StockType.getValueByType(stockItemDO.getStockMarket()));
            if(realtimeData != null){
                detailVO.setPrice(realtimeData.getPrice());
                detailVO.setUpdown(realtimeData.getUpdown());
                BigDecimal percent = BigDecimal.valueOf(realtimeData.getPercent()).multiply(BigDecimal.valueOf(100)).setScale(2, BigDecimal.ROUND_HALF_UP);
                detailVO.setPercent(percent);
            }
        }

        DayTradeRecordDO recordDO = new DayTradeRecordDO();
        recordDO.setUserId(userId);
        recordDO.setPlanType(StockConstants.STOCK_STRATEGY_GRID);
        recordDO.setComposeId(planDO.getComposeId());
        recordDO.setStockCode(dayTradePlanVO.getStockCode());

        Page<DayTradeRecordDO> page = dayTradeRecordService.queryByCondition(recordDO, 0, Integer.MAX_VALUE);
        List<DayTradeRecordVO> recordVOList = PropertiesCopyUtil.copyPropertiesByList(page.getContent(),DayTradeRecordVO.class);

        List<DayTradeProfitDO> profitDOList = dayTradeProfitService.findTradeProfitList(planDO.getComposeId(), StockConstants.STOCK_STRATEGY_T0, userId);
        List<DayTradeProfitVO> profitVOS = PropertiesCopyUtil.copyPropertiesByList(profitDOList, DayTradeProfitVO.class);
        if(!CollectionUtils.isEmpty(profitVOS)){
            Map<Long, DayTradeRecordVO> recordMap = recordVOList.stream().collect(Collectors.toMap(DayTradeRecordVO::getId, Function.identity(), (k1, k2) -> k2));

            for (DayTradeProfitVO profitVO : profitVOS) {
                DayTradeRecordVO buyRecordVO = recordMap.get(profitVO.getBuyTradeId());
                DayTradeRecordVO sellRecordVO = recordMap.get(profitVO.getSellTradeId());
                profitVO.setSellTradeVO(sellRecordVO);
                profitVO.setBuyTradeVO(buyRecordVO);
            }
        }

        detailVO.setBuyNumber(0L);
        detailVO.setSellNumber(0L);
        if(!CollectionUtils.isEmpty(recordVOList)){
            long buyNumber = 0,sellNumber = 0;
            for (DayTradeRecordVO item : recordVOList) {
                if(item.getType() == TradeType.BUY.getType()){
                    buyNumber++;
                }else{
                    sellNumber++;
                }
            }
            detailVO.setBuyNumber(buyNumber);
            detailVO.setSellNumber(sellNumber);
        }

        detailVO.setTradeRecordList(recordVOList);
        detailVO.setTradeProfitList(profitVOS);

        return ResultUtil.success(detailVO);
    }


    @GetMapping("/queryTradeRecordByPage")
    public Result recordList(@RequestParam Long planId,
                                              @RequestParam String code,
                                              @RequestParam(required = false) Integer pageNumber,
                                              @RequestParam(required = false) Integer pageSize){
//        Long userId = UserSecurityUtil.getUserId();
//        PageRequest pageRequest = PageUtil.buildPageRequest(pageNumber, pageSize);
//
//        Page<DayTradeRecordDO> page = dayTradeRecordService.queryByCondition(planId, code, StockConstants.STOCK_STRATEGY_GRID, pageRequest);
//        return ResultUtil.success(page);
        return ResultUtil.success(null);
    }


    @PostMapping("/save")
    public Result savePlan(@RequestBody DayTradePlanVO dataObj){
        Long userId = UserSecurityUtil.getUserId();
        if(dataObj.getComposeId() == null)
            return ResultUtil.error("模拟组合ID为空");

        if(dataObj.getStockCode() == null)
            return ResultUtil.error("成交股票代码为空");

        if(dataObj.getStockName() == null)
            return ResultUtil.error("成交股票名称为空");

        if(dataObj.getTradeStockNum() == null)
            return ResultUtil.error("每笔交易数量为空");

        if(dataObj.getMonitorDecreasePer() == null || dataObj.getMonitorIncreasePer() == null)
            return ResultUtil.error("监控涨幅或跌幅为空");

        if(dataObj.getTradeDecreasePer() == null || dataObj.getTradeIncreasePer() == null)
            return ResultUtil.error("交易涨幅或跌幅为空");

//        if(dataObj.getTradePriceType() == null)
//            return ResultUtil.error("委托价类型为空");
        //todo 其他参数校验
        //检查是否持仓该股票

        if(dataObj.getId() == null) {
            dataObj.setCreateId(userId);
            dataObj.setCreateTime(new Date());
        }else{
            dataObj.setUpdateId(userId);
            dataObj.setUpdateTime(new Date());
        }


//        DayTradePlanDO gridTradePlanDO = PropertiesCopyUtil.copyProperties(dataObj, DayTradePlanDO.class);
        dataObj.setCode(dataObj.getStockCode());
        return ResultUtil.success( tradePlanService.add(dataObj));
    }

    @PostMapping("/start/{id}")
    public Result startPlan(@PathVariable Long id){
        Long userId = UserSecurityUtil.getUserId();
        DayTradePlanVO dayTradePlanDO = tradePlanService.startPlan(id, userId.intValue());
        if(dayTradePlanDO == null) return ResultUtil.error("启动计划失败");

        return ResultUtil.success(null);
    }

    @PostMapping("/stop/{id}")
    public Result stopPlan(@PathVariable Long id){
        Long userId = UserSecurityUtil.getUserId();
        DayTradePlanVO dayTradePlanDO = tradePlanService.stopPlan(id, userId.intValue());
        if(dayTradePlanDO == null) return ResultUtil.error("停止计划失败");
        return ResultUtil.success(null);
    }

    @PostMapping("/delete/{id}")
    public Result deletePlan(@PathVariable Long id){
        Long userId = UserSecurityUtil.getUserId();
        DayTradePlanVO dayTradePlanDO = tradePlanService.remove(id, userId.intValue());
        if(dayTradePlanDO == null)  return ResultUtil.error("停止计划失败");
        return ResultUtil.success(null);
    }

//    @Autowired
//    T0StockMonitorService monitorService;
//
//    @GetMapping("/test")
//    public Result test(){
//        String json = "{\"code\":\"600048\",\"planType\":\"t0\",\"personId\":3,\"planId\":2,\"composeId\":8,\"realtimeStockData\":{\"symbol\":\"600048\",\"code\":\"0600048\",\"arrow\":\"↑\",\"update\":\"2020/11/25 10:11:42\",\"type\":\"SH\",\"percent\":0.010131,\"high\":16.95,\"low\":16.73,\"price\":16.95,\"yestclose\":16.78,\"turnover\":286952184,\"askvol1\":120700,\"askvol2\":61900,\"askvol3\":54400,\"askvol4\":130900,\"askvol5\":123300,\"volume\":17040924,\"ask5\":16.99,\"bidvol1\":54800,\"ask2\":16.96,\"bidvol2\":27300,\"ask1\":16.95,\"bidvol3\":33100,\"ask4\":16.98,\"bid5\":16.9,\"bidvol4\":1200,\"ask3\":16.97,\"bidvol5\":19100,\"bid3\":16.92,\"name\":\"保利地产\",\"bid4\":16.91,\"bid1\":16.94,\"bid2\":16.93,\"time\":\"2020/11/25 10:11:42\",\"updown\":0.17,\"open\":16.89,\"status\":0},\"tradeType\":\"SELL\"}\n";
//        MonitorActionInfo actionInfo = JSON.parseObject(json, MonitorActionInfo.class);
//        List<DayTradePlanDO> planDOS = tradePlanService.queryTradingPlanList();
//        if(planDOS.size() != 0) {
//            DayTradePlanDO planDO = planDOS.get(0);
//            monitorService.doTradeAction(actionInfo.getRealtimeStockData(),planDO,true);
//        }
//        return ResultUtil.success(null);
//    }


}
